﻿#include "MouseWidget.h"
#include "Widgets/WidgetTree.h"
#include "Event/MouseEvent.h"
#include "Output/Console.h"

RMouseWidget::RMouseWidget()
{
}

void RMouseWidget::FirstTimeInitializeObject()
{
    Drag=NewObject<RMouseDrag>(this);
}

void RMouseWidget::Tick(float DeltaSeconds)
{
    if(RenderState==ERenderState::Normal)
    {
        //注册对应的区域
        GetWidgetTree()->HoldGrids(this);
        bIsHoldGrid=true;
        
        DebugMouseWidgetID=GetWidgetTree()->CreateMouseWidgetDebugID();

    }

    Super::Tick(DeltaSeconds);
}


void RMouseWidget::Unregister()
{
    if(GetWidgetTree() && bIsHoldGrid )
    {
        GetWidgetTree()->UnHoldGrids(this);
        bIsHoldGrid=false;
    }
    Super::Unregister();
}

//是否输出鼠标事件调试信息
#ifdef USING_SOURCE_LOCATION
    //设为1输出调试信息，设为0不输出
    #define DEBUG_MOUSE_WIDGET_INTERACTION 0 
#else
    #define DEBUG_MOUSE_WIDGET_INTERACTION 0
#endif



bool RMouseWidget::ProcessMouseEvent(const SMouseButtonEvent& MouseEvent)
{
    auto Consumed=ProcessMouseEventInner(MouseEvent);
    if(bPreventCovoredWidgetResponse.Get())
    {
        //强制消耗鼠标事件
        return true;
    }
    return Consumed;
}

bool RMouseWidget::ProcessMouseEventInner(const SMouseButtonEvent &MouseEvent)
{
    if(Drag->bIsEnabled.Get() && Drag->ProcessMouseEvent(Tree,MouseEvent))
    {
        return true;
    }

    switch(MouseEvent.GetType())
    {

        case EMouseEventType::Move:
        {
            if(OnMoved.IsBound())
            {
// #if DEBUG_MOUSE_WIDGET_INTERACTION
//                 WH::PrintLine(U"鼠标移动: {}",WH::ToString(CreatePosition));
// #endif
                return OnMoved.Broadcast(MouseEvent);
            }
            return false;
        }
        break;

        case EMouseEventType::ButtonDown:
        {
            if (MouseEvent.IsDoubleClick())
            {
                if(OnDoubleClicked.IsBound())
                {
#if DEBUG_MOUSE_WIDGET_INTERACTION
                WH::PrintLine(U"鼠标双击: {}",WH::ToString(CreatePosition));
#endif
                    return OnDoubleClicked.Broadcast(MouseEvent);
                }
            }

            if(OnPressed.IsBound())
            {
#if DEBUG_MOUSE_WIDGET_INTERACTION
                WH::PrintLine(U"鼠标按下: {}",WH::ToString(CreatePosition));
#endif
                return OnPressed.Broadcast(MouseEvent);
            }
            return false;

        }
        break;

        case EMouseEventType::ButtonUp:
        {

            //address selection ,selecton will not consume click event (for easy understand)
            if(IsInSelectionGroup()
                &&Selection->Group->MouseButton==MouseEvent.GetButton()
                // && Selection->Group->DoubleClick== MouseEvent.IsDoubleClick()
                )
            {
                Selection->Group->Select(Selection->SelectTarget);
            }


            if(AutoFocusTarget &&  MouseEvent.GetButton()==EMouseButton::Left)
            {
#if DEBUG_MOUSE_WIDGET_INTERACTION
                WH::PrintLine(U"给键盘焦点: {}",WH::ToString(CreatePosition));
#endif
                GetWidgetTree()->FocusWidget(AutoFocusTarget);

                // if(bAutoFocusConsumesEvent)
                // {
                //     return true;
                // }
            }

            
            if(OnReleased.IsBound())
            {   
                bool bConsume=OnReleased.Broadcast(MouseEvent);
                if(bConsume)
                {
#if DEBUG_MOUSE_WIDGET_INTERACTION
                    WH::PrintLine(U"鼠标弹起: {}",WH::ToString(CreatePosition));
#endif
                    return true;
                }
            }

            
            if(OnClicked.IsBound())
            {
#if DEBUG_MOUSE_WIDGET_INTERACTION
                WH::PrintLine(U"鼠标单击: {}",WH::ToString(CreatePosition));
#endif
                return OnClicked.Broadcast(MouseEvent);
            }
            
            break;
        }
    
        case EMouseEventType::WheelRoll:
        {
            if(OnWheeled.IsBound())
            {
#if DEBUG_MOUSE_WIDGET_INTERACTION
                WH::PrintLine(U"鼠标滚动: {}",WH::ToString(CreatePosition));
#endif
                return OnWheeled.Broadcast(MouseEvent);
            }
            break;
        }

        case EMouseEventType::DropFile:
        {
            if(OnFileDropped.IsBound())
            {
#if DEBUG_MOUSE_WIDGET_INTERACTION
                WH::PrintLine(U"拖放文件: {}",WH::ToString(CreatePosition));
#endif
                return OnFileDropped.Broadcast(MouseEvent);
            }
            break;
        }
    }

    return false;
}

SVec2 RMouseWidget::GetMousePositionInContent()
{
    return ToLocalPosition(GetWidgetTree()->GetMousePositionInContent());
}

void RMouseWidget::JoinSelectionGroup(RWidgetWeakPtr SelectTarget,std::shared_ptr<CMouseSelectionGroup> Group)
{
    if(IsInSelectionGroup())
    {
        ExitSelectionGroup();
    }
    Selection=CMouseSelectionGroupItem(SelectTarget,Group);
}

bool RMouseWidget::IsInSelectionGroup()
{
    return Selection.HasValue();
}

void RMouseWidget::ExitSelectionGroup()
{
    if(IsInSelectionGroup())
    {
        if(Selection->Group->GetSelectedWidget()==Selection->SelectTarget)
        {
            Selection->Group->Unselect();
        }

        Selection.Reset();
    }

}